﻿namespace IceCS.Puke.Core
{
    public partial class Card
    {
        /*
         * 重载思路
         * ==:通过特征去判断
         * >:通过特征去比较
         * >=: (>) + (==)
         * !=: !(==)
         * <: !(>=)
         * <=: !(>)
         * 所以六种运算符我们只要实现两种就行，其余的可以通过组合来实现
         */

        #region 运算符重写
        /// <summary>
        /// 重载等于运算符,判断 card1==card2
        /// </summary>
        /// <param name="card1">卡片1</param>
        /// <param name="card2">卡片2</param>
        /// <returns></returns>
        public static bool operator ==(Card card1, Card card2)
        {
            //必须转换为 object 进行比较，直接 card1 == null 等于调用自身
            //是死循环,另外 null == null 结果应该是true
            if (card1 is null)
            {
                return card2 is null;
            }
            if (card2 is null)
            {
                return false;
            }
            return card1.GetHashCode() == card2.GetHashCode();
        }

        // <summary>
        /// 重载大于运算符,判断 card1&gt;card2
        /// </summary>
        /// <param name="card1">卡片1</param>
        /// <param name="card2">卡片2</param>
        /// <returns></returns>
        public static bool operator >(Card card1, Card card2)
        {
            //必须转换为 object 进行比较，直接 card1 == null 等于调用自身
            //是死循环,另外 null == null 结果应该是true
            if (card1 is null)
            {
                return card2 is null;
            }
            if (card2 is null)
            {
                return false;
            }

            //只有花色相同才比较大小
            if (card1.Suit == card2.Suit)
            {
                //如果A不是最大
                if (!Deck.IsAceHigh)
                {
                    return card1.Rank > card2.Rank;
                }

                //如果A是最大，且卡片1是A
                if (card1.Rank == Rank.Ace)
                {
                    //则判断卡片2是不是A
                    return card2.Rank != Rank.Ace;
                }
                //如果A是最大，且卡片2是A
                if (card2.Rank == Rank.Ace)
                {
                    return false;
                }
                //否则正常比较
                return card1.Rank > card2.Rank;
            }

            //如果使用王牌花色，且card2的花色是王牌花色，则false
            return Deck.UseTrumps && card1.Suit == Deck.Trump;
        }

        /// <summary>
        /// 重载不等于运算符,判断 card1!=card2
        /// </summary>
        /// <param name="card1">卡片1</param>
        /// <param name="card2">卡片2</param>
        /// <returns></returns>
        public static bool operator !=(Card card1, Card card2) => !(card1 == card2);

        /// <summary>
        /// 重载 &lt; 运算符
        /// </summary>
        /// <param name="card1"></param>
        /// <param name="card2"></param>
        /// <returns></returns>
        public static bool operator <(Card card1, Card card2) => !(card1 >= card2);
        /// <summary>
        /// 重载 &gt;= 运算符
        /// </summary>
        /// <param name="card1"></param>
        /// <param name="card2"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public static bool operator >=(Card card1, Card card2)
        {
            return (card1 > card2) || (card1 == card2);
        }
        /// <summary>
        /// 重载 &lt;= 运算符
        /// </summary>
        /// <param name="card1"></param>
        /// <param name="card2"></param>
        /// <returns></returns>
        public static bool operator <=(Card card1, Card card2) => !(card1 > card2);

        #endregion

        #region Equals 方法重写
        /// <summary>重载Equals方法,确定指定的对象是否等于当前对象。</summary>
        /// <param name="obj">要与当前对象进行比较的对象。</param>
        /// <returns>
        ///   如果指定的对象等于当前对象，则为 <see langword="true" />，否则为 <see langword="false" />。
        /// </returns>
        public override bool Equals(object card) => Equals(card as Card);

        /// <summary>重载Equals方法,确定指定的对象是否等于当前对象。</summary>
        /// <param name="card">要与当前对象进行比较的card对象。</param>
        /// <returns>
        ///   如果指定的对象等于当前对象，则为 <see langword="true" />，否则为 <see langword="false" />。
        /// </returns>
        protected bool Equals(Card card)
        {
            return this == card;
        }

        /// <summary>
        ///  静态 Equals 方法
        /// </summary>
        /// <param name="card1">卡片1</param>
        /// <param name="card2">卡片2</param>
        /// <returns></returns>
        public static bool Equals(Card card1, Card card2) => card1 == card2;

        #endregion
    }
}
